package com.sy.simpleegg.room

import android.util.Log
import androidx.sqlite.db.SimpleSQLiteQuery
import androidx.sqlite.db.SupportSQLiteQuery
import com.sy.simpleegg.app.App
import com.sy.simpleegg.bean.ChannelBean
import com.sy.simpleegg.constant.PayState
import com.sy.simpleegg.constant.PayType
import com.sy.simpleegg.platform.BackstagePlatform
import com.sy.simpleegg.room.database.AppDatabase
import com.sy.simpleegg.room.entity.CashPackageEntity
import com.sy.simpleegg.room.entity.CoinEntity
import com.sy.simpleegg.room.entity.ControlBoardEntity
import com.sy.simpleegg.room.entity.GoodEntity
import com.sy.simpleegg.room.entity.OrderEntity
import com.sy.simpleegg.room.entity.OutEntity
import com.sy.simpleegg.room.entity.SaveCoinEntity
import com.sy.simpleegg.room.repository.CashPackageRepository
import com.sy.simpleegg.room.repository.CoinRepository
import com.sy.simpleegg.room.repository.ControlBoardRepository
import com.sy.simpleegg.room.repository.GoodRepository
import com.sy.simpleegg.room.repository.OrderRepository
import com.sy.simpleegg.room.repository.OutRepository
import com.sy.simpleegg.room.repository.SaveCoinRepository
import com.sy.simpleegg.util.DateTimeUtil
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

object RoomUtil {

    private val database: AppDatabase by lazy {AppDatabase.get(App.instance)}
//    private var database: AppDatabase? = null

    private val goodRepository: GoodRepository by lazy { GoodRepository(database.goodDao()) }
    private val orderRepository: OrderRepository by lazy { OrderRepository(database.orderDao()) }
    private val outRepository: OutRepository by lazy { OutRepository(database.outDao()) }
    private val coinRepository: CoinRepository by lazy { CoinRepository(database.coinDao()) }
    private val cashPackageDao: CashPackageRepository by lazy { CashPackageRepository(database.cashPackageDao()) }
    private val controlBoardRepository: ControlBoardRepository by lazy { ControlBoardRepository(database.controlBoardDao()) }
    private val saveCoinRepository: SaveCoinRepository by lazy { SaveCoinRepository(database.saveCoinDao()) }

    fun start(){
//        database = AppDatabase.get(App.instance)
    }
    /******************************************商品操作****************************************************/

    /**
     * 添加商品数据
     * @param goodEntities 商品列表
     */
    suspend fun insertGood(goodEntities: MutableList<GoodEntity>){
//        goodRepository.deleteAll()
        goodRepository.insertAll(goodEntities)
    }

    /**
     * 获取全部商品数据
     * return 商品列表
     */
    suspend fun getAllGood(): MutableList<GoodEntity>?{
        return goodRepository.getAllGoods()
    }

    /**
     * 获取最新商品数据
     * return 商品列表
     */
    suspend fun getLastGood(platform: BackstagePlatform): MutableList<GoodEntity>?{
        return goodRepository.getLastGoods(platform)
    }

    /**
     * 删除商品数据
     * @param goodEntity 商品实体
     */
    suspend fun deleteGoodA(goodEntity: GoodEntity){
        goodRepository.delete(goodEntity)
    }

    /******************************************订单操作****************************************************/
    /**
     * 获取全部订单
     * @return 订单列表
     */
    suspend fun orderGetAll(): List<OrderEntity>?{
        return orderRepository.getAll()
    }

    /**
     * 通过日期获取订单
     * @param date 日期
     * @return 订单列表
     */
    suspend fun orderGetByDate(date: String): MutableList<OrderEntity>?{
        return orderRepository.getByDate(date)
    }

    /**
     * 通过uuid获取订单数据
     * @param uuid uuid
     * @return 订单列表
     */
    suspend fun orderGetByUuid(uuid: String): List<OrderEntity>?{
        return orderRepository.getByUuid(uuid)
    }

    /**
     * 通过订单号获取订单数据
     * @param orderNumber 订单号
     * @return 订单列表
     */
    suspend fun orderGetByOrderNumber(orderNumber: String): List<OrderEntity>?{
        return orderRepository.getByOrderNumber(orderNumber)
    }

    /**
     * 通过payuuid获取订单数据
     * @param orderNumber 订单号
     * @return 订单列表
     */
    suspend fun orderGetByPayUUID(payUUID: String): List<OrderEntity>?{
        return orderRepository.getByPayUUID(payUUID)
    }

    /**
     * 获取最新纸钞订单数据
     * @param platform 平台
     * @return 订单列表
     */
    suspend fun orderCashLast(platform: BackstagePlatform): MutableList<OrderEntity>?{
        return orderRepository.getLastCashOrder(platform)
    }

    /**
     * 获取最新扫码订单数据
     * @param platform 平台
     * @return 订单列表
     */
    suspend fun orderNormalLast(platform: BackstagePlatform): MutableList<OrderEntity>?{
        return orderRepository.getLastNormalOrder(platform)
    }

    /**
     * 获取最新扫码订单数据
     * @param platform 平台
     * @return 订单列表
     */
    suspend fun orderNormalAmountLast(platform: BackstagePlatform, coins: String): MutableList<OrderEntity>?{
        return orderRepository.getLastNormalAmountOrder(platform, coins)
    }

    /**
     * 获取最新充值订单数据
     * @param platform 平台
     * @return 订单列表
     */
    suspend fun orderRechargeLast(platform: BackstagePlatform): MutableList<OrderEntity>?{
        return orderRepository.getLastRechargeOrder(platform)
    }

    /**
     * 订单更新
     * @param orderEntity 更新的数据
     */
    suspend fun orderUpdate(vararg orderEntity: OrderEntity){
        orderRepository.update(*orderEntity)
    }

    /**
     * 订单更新
     * @param orderEntity 更新的数据
     */
    suspend fun orderUpdateByUuid(uuid: String, payState: PayState){
        orderRepository.updateByUuid(uuid, payState)
    }

    /**
     * 订单更新
     * @param uuid 更新的数据
     * @param payType 支付状态
     */
    suspend fun orderUpdatePayType(uuid: String, payType: PayType){
        orderRepository.updatePayType(uuid, payType)
    }

    /**
     * 添加订单
     * @param orderEntity 订单
     */
    suspend fun orderInsert(orderEntity: OrderEntity){
        orderRepository.insert(orderEntity)
    }

    /**
     * 添加订单
     * @param orderEntities 订单列表
     */
    suspend fun orderInsertAll(orderEntities: List<OrderEntity>){
        orderRepository.insertAll(orderEntities)
    }

    /**
     * 删除订单
     * @param orderEntity 目标订单
     */
    suspend fun orderDelete(orderEntity: OrderEntity){
        orderRepository.delete(orderEntity)
    }

    /**
     * 删除全部订单
     */
    suspend fun orderDeleteAll(){
        orderRepository.deleteAll()
    }

    /**
     * 通过uuid删除订单
     * @param uuid uuid
     */
    suspend fun orderDeleteByUuid(uuid: String){
        orderRepository.deleteByUuid(uuid)
    }

    /**
     * 通过订单号删除订单
     * @param orderNumber 订单号
     */
    suspend fun orderDeleteByOrderNumber(orderNumber: String){
        orderRepository.deleteByOrderNumber(orderNumber)
    }

    /**
     * 更新出币数
     * @param orderNumber 订单号
     * @param coins 出币数
     */
    suspend fun updateOrderRealCoins(orderNumber: String, coins: String){
        orderRepository.updateRealCoins(orderNumber, coins)
    }

    /**
     * 获取提币订单
     * @param orderNumber 订单号
     */
    suspend fun orderWithdrawalByOrderNumber(orderNumber: String): MutableList<OrderEntity>?{
        return orderRepository.getOrderByOrderNumber(orderNumber, PayType.WITHDRAWAL)
    }

    /**
     * 获取核销订单
     * @param orderNumber 订单号
     */
    suspend fun orderWriteOffByOrderNumber(orderNumber: String): MutableList<OrderEntity>?{
        return orderRepository.getOrderByOrderNumber(orderNumber, PayType.WRITEOFF)
    }

    /**
     * 获取时间段内未出币完成的订单
     * @param startDate 起始日期
     * @param endDate 结束日期
     */
    suspend fun orderSupplement(startDate: String, endDate: String): MutableList<OrderEntity>?{
        return orderRepository.getOrderSupplement(startDate, endDate, PayState.COMPLETE)
    }

    /**
     * 更新出币数据
     * @param id
     * @param realAmount 实际出币数
     */
    suspend fun setOrderRealAmount(id: Long, realAmount: String){
        orderRepository.setRealAmount(id, realAmount)
    }

    /**
     * 查询是否存在订单
     * @param platform
     * @param orderNumber 订单号
     */
    suspend fun verifyOrderNumber(platform: BackstagePlatform, orderNumber: String): Int{
        return orderRepository.verifyOrderNumber(platform, orderNumber)
    }

    /******************************************出货操作****************************************************/

    /**
     * 获取全部出货数据
     * @return 出货列表
     */
    suspend fun outGetAll(): List<OutEntity>?{
        return outRepository.getAll()
    }

    /**
     * 通过uuid获取出货数据
     * @param uuid uuid
     * @return 出货列表
     */
    suspend fun outGetByUuid(uuid: String): List<OutEntity>?{
        return outRepository.getByUuid(uuid)
    }

    /**
     * 通过id更新出货状态
     * @param id id
     * @param state 0-未处理 1-出货成功 2-出货失败
     */
    suspend fun outUpdateById(id: Long, state: Int){
        outRepository.updateById(id, state)
    }

    /**
     * 通过uuid更新出货状态
     * @param uuid uuid
     * @param state 0-未处理 1-出货成功 2-出货失败
     */
    suspend fun outUpdateByUuid(uuid: String, state: Int){
        outRepository.updateByUuid(uuid, state)
    }

    /**
     * 添加出货数据
     * @param outEntity 数据实体
     */
    suspend fun outInsert(outEntity: OutEntity){
        outRepository.insert(outEntity)
    }

    /**
     * 添加出货数据
     * @param outEntities 出货列表
     */
    suspend fun outInsertAll(outEntities: List<OutEntity>){
        outRepository.insertAll(outEntities)
    }

    /**
     * 删除出货数据
     * @param outEntity 目标数据实体
     */
    suspend fun outDelete(outEntity: OutEntity){
        outRepository.delete(outEntity)
    }

    /**
     * 删除全部出货数据
     */
    suspend fun outDeleteAll(){
        outRepository.deleteAll()
    }

    /**
     * 通过id更新出货状态
     * @param uuid uuid
     */
    suspend fun outDeleteByUuid(uuid: String){
        outRepository.deleteByUuid(uuid)
    }

    /**
     * 通过id删除出货数据
     * @param id id
     */
    suspend fun outDeleteById(id: Long){
        outRepository.deleteById(id)
    }
    /******************************************硬币操作****************************************************/

    suspend fun saveCoins(coinEntity: CoinEntity){
        coinRepository.insert(coinEntity)
    }

    suspend fun coinUpdate(coinEntity: CoinEntity){
        coinRepository.update(coinEntity)
    }

    suspend fun getLastCoin(): MutableList<CoinEntity>?{
        return coinRepository.getLastCoin()
    }

    suspend fun getClearData(startDate: String, endDate: String): MutableList<CoinEntity>?{
        return coinRepository.getClearData(startDate, endDate)
    }

    suspend fun getCoinByDate(date: String): MutableList<CoinEntity>?{
        return coinRepository.getByDate(date)
    }

    private fun getChannelSql(channelParams: MutableList<ChannelBean>): MutableList<SupportSQLiteQuery>{
        val sqlList: MutableList<SupportSQLiteQuery> = mutableListOf()
        if (channelParams.isEmpty()){
            return sqlList
        }

        channelParams.forEach {
            val sb = StringBuilder(" UPDATE tb_good SET")
            var itemCount = 0
            if (!it.channelName.isNullOrBlank()){
                sb.append(" channelName = '${it.channelName}',")
                itemCount ++
            }
            if (it.channelCapacity != -1){
                sb.append(" channelCapacity = '${it.channelCapacity}',")
                itemCount ++
            }
            if (!it.goodId.isNullOrBlank()){
                sb.append(" goodId = '${it.goodId}',")
                itemCount ++
            }
            if (!it.goodName.isNullOrBlank()){
                sb.append(" goodName = '${it.goodName}',")
                itemCount ++
            }
            if (!it.price.isNullOrBlank()){
                sb.append(" price = '${it.price}',")
                itemCount ++
            }
            if (!it.cost.isNullOrBlank()){
                sb.append(" cost = '${it.cost}',")
                itemCount ++
            }
            if (!it.gamePrice.isNullOrBlank()){
                sb.append(" gamePrice = '${it.gamePrice}',")
                itemCount ++
            }
            if (!it.probability.isNullOrBlank()){
                sb.append(" probability = '${it.probability}',")
                itemCount ++
            }
            if (it.stock != -1){
                sb.append(" stock = '${it.stock}',")
                itemCount ++
            }
            if (it.type != -1){
                sb.append(" type = '${it.type}',")
                itemCount ++
            }
            if (!it.typeName.isNullOrBlank()){
                sb.append(" typeName = '${it.typeName}',")
                itemCount ++
            }
            if (!it.imgUrl.isNullOrBlank()){
                sb.append(" imgUrl = '${it.imgUrl}',")
                itemCount ++
            }
            if (it.enable != -1){
                sb.append(" enable = '${it.enable}',")
                itemCount ++
            }
            if (!it.info.isNullOrBlank()){
                sb.append(" info = '${it.info}',")
                itemCount ++
            }
            if (itemCount > 0){
                var tempSqlStr = sb.toString()
                tempSqlStr = tempSqlStr.substring(0, tempSqlStr.length - 1)
                val resultSqlStr = tempSqlStr + " WHERE channel = '${it.channel}'"
                Log.d(javaClass.simpleName, "sql=$resultSqlStr")
                sqlList.add(SimpleSQLiteQuery(resultSqlStr))
            }
        }
        return sqlList
    }

    /******************************************纸钞套餐****************************************************/
    /**
     * 获取对应平台的纸钞数据数量
     * @param platform 接入平台
     */
    suspend fun getCashPackageCount(platform: BackstagePlatform): Long{
        return cashPackageDao.getCashPackageCount(platform)
    }

    /**
     * 获取纸钞数据
     * @param platform 接入平台
     */
    suspend fun getCashPackageData(platform: BackstagePlatform): MutableList<CashPackageEntity>?{
        return cashPackageDao.getCashPackageData(platform)
    }

    /**
     * 插入或更新纸钞数据
     * @param cashPackageList 纸钞数据
     */
    suspend fun cashPackageInsert(cashPackageList: MutableList<CashPackageEntity>){
        return cashPackageDao.insertAll(cashPackageList)
    }

    /**
     * 删除单个纸钞数据
     * @param cashPackageEntity 纸钞数据
     */
    suspend fun cashPackageDelete(cashPackageEntity: CashPackageEntity){
        return cashPackageDao.delete(cashPackageEntity)
    }

    /**
     * 删除所有纸钞数据
     */
    suspend fun cashPackageDeleteAll(){
        return cashPackageDao.deleteAll()
    }

    /******************************************控制板连接状态****************************************************/
    /**
     * 获取全部数据
     */
    suspend fun getAllControlBoard(): MutableList<ControlBoardEntity>?{
        return withContext(Dispatchers.IO){
            controlBoardRepository.getAll()
        }
    }

    /**
     * 获取最新的数据
     * @param type 控制板类型
     */
    suspend fun getLastControlBoard(type: Int): MutableList<ControlBoardEntity>?{
        return withContext(Dispatchers.IO){
            controlBoardRepository.getLast(type)
        }
    }

    /**
     * 插入新数据
     * @param controlBoardEntity 新数据
     */
    suspend fun insertControlBoard(controlBoardEntity: ControlBoardEntity){
        withContext(Dispatchers.IO){
            controlBoardRepository.insert(controlBoardEntity)
        }
    }

    /**
     * 删除控制板记录
     * @param controlBoardEntity 目标数据
     */
    suspend fun deleteControlBoard(controlBoardEntity: ControlBoardEntity){
        withContext(Dispatchers.IO){
            controlBoardRepository.delete(controlBoardEntity)
        }
    }

    /**
     * 删除控制板全部记录
     */
    suspend fun deleteAllControlBoard(){
        withContext(Dispatchers.IO){
            controlBoardRepository.deleteAll()
        }
    }

    /**
     * 当天的数据
     * @param type 控制板类型
     */
    suspend fun getCurrentDateControlBoard(type: Int): MutableList<ControlBoardEntity>?{
        val currentDate = DateTimeUtil.nowDate
        return withContext(Dispatchers.IO){
            controlBoardRepository.getDateData(type, currentDate)
        }
    }

    /**
     * x天内的数据
     * @param type 控制板类型
     * @param lastDays 过去天数
     */
    suspend fun getDayAgoControlBoard(type: Int, lastDays: Int): MutableList<ControlBoardEntity>?{
        val currentDate = DateTimeUtil.nowDate
        val agoDate = DateTimeUtil.getDaysAgoDate(lastDays)
        return withContext(Dispatchers.IO){
            controlBoardRepository.getBetweenDate(type, currentDate, agoDate)
        }
    }

    /******************************************存币订单****************************************************/
    /**
     * 获取全部数据
     */
    suspend fun getAllSaveCoin(): MutableList<SaveCoinEntity>?{
        return withContext(Dispatchers.IO){
            saveCoinRepository.getAll()
        }
    }

    /**
     * 获取存币数据
     * @param sn 存币订单号
     */
    suspend fun getSaveCoinBySn(sn: String): MutableList<SaveCoinEntity>?{
        return withContext(Dispatchers.IO){
            saveCoinRepository.getBySn(sn)
        }
    }

    /**
     * 获取需要上报的存币数据
     */
    suspend fun getSaveCoinCanReport(): MutableList<SaveCoinEntity>?{
        return withContext(Dispatchers.IO){
            saveCoinRepository.getCanReport()
        }
    }

    /**
     * 更新存币步骤
     * @param sn 订单号
     * @param step 步骤
     */
    suspend fun updateSaveCoinStep(sn: String, step: Int){
        withContext(Dispatchers.IO){
            saveCoinRepository.updateStepBySn(sn, step)
        }
    }

    /**
     * 更新存币数据
     * @param saveCoinEntity 目标数据
     */
    suspend fun updateSaveCoin(saveCoinEntity: SaveCoinEntity){
        withContext(Dispatchers.IO){
            saveCoinRepository.update(saveCoinEntity)
        }
    }

    /**
     * 更新存币数
     * @param sn 订单号
     * @param coins 存币数
     */
    suspend fun updateSaveCoin(sn: String, coins: String){
        withContext(Dispatchers.IO){
            saveCoinRepository.update(sn, coins)
        }
    }

    /**
     * 插入数据
     */
    suspend fun insertSaveCoin(saveCoinEntity: SaveCoinEntity){
        withContext(Dispatchers.IO){
            saveCoinRepository.insert(saveCoinEntity)
        }
    }

    /**
     * 删除存币订单
     * @param saveCoinEntity 目标订单数据
     */
    suspend fun deleteSaveCoin(saveCoinEntity: SaveCoinEntity){
        return withContext(Dispatchers.IO){
            saveCoinRepository.delete(saveCoinEntity)
        }
    }

    /**
     * 删除所有存币订单
     */
    suspend fun deleteAllSaveCoin(){
        return withContext(Dispatchers.IO){
            saveCoinRepository.deleteAll()
        }
    }

    /**
     * 删除存币订单
     * @param sn 目标订单号
     */
    suspend fun deleteSaveCoinBySn(sn: String){
        return withContext(Dispatchers.IO){
            saveCoinRepository.deleteBySn(sn)
        }
    }
}